import re
import sys
from ModelHelper import *
#
# The global patten used:
#
latlong_patten = re.compile("^-?\d+\.(\d)+$")
name_patten = re.compile("^[a-zA-Z_\s0-9,']+$")
formal_name_patten = re.compile("^[a-zA-Z_\-0-9,]+$")
type_patten = re.compile("^[a-zA-Z]+$")
nation_patten = re.compile("^[a-zA-Z\s,]+$")
email_patten = re.compile("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
phone_patten = re.compile("[0-9\(\)\s]+")
description_patten = re.compile(".+")
data_patten = re.compile(".+")
address_patten = re.compile("[a-zA-Z0-9\s]+")
url_patten = re.compile("((https?):((//)|(\\\\)))?[\w\d:#@%/;$()~_?\+-=\\\.&]*")
password_patten = re.compile("[a-zA-Z\d#@%]+")
number_patten = re.compile("[0-9-]+")  #FIX ME: This is really buggy
number_range_patten = re.compile("([0-9-]+)\-([0-9]+)")  #FIX ME: This is really buggy
day_patten = re.compile("((Sun)|(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|,)+")  #FIX ME: This is really buggy
layout_patten = re.compile("[a-zA-Z-]+")  #FIX ME: This is really buggy
time_range_patten = re.compile("[0-9]{1,2}:[0-9]{2}")
color_patten = re.compile("#[0-9a-fA-F]+")
path_patten = re.compile("^[a-zA-Z_\-0-9,]+/[a-zA-Z_\-0-9,]+$")
special_description_patten = re.compile(".+")
special_rate_patten = re.compile(".+")
special_start_patten = re.compile(".+")
special_end_patten = re.compile(".+")
oz_state_patten = re.compile(".+")
region_patten = re.compile(".+")
city_patten = re.compile(".+")
keywords_patten = re.compile(".+")
#
# Validate groups used to validate request input
#

imagelink_handler = {'path':(path_patten,(lambda x:x),lambda x,v :(x.update(path = v)))}

color_theme_handler = {'background':(color_patten,(lambda x:x),lambda x,v :(x.update(background = v)))
  ,'border':(color_patten,(lambda x:x),lambda x,v:(x.update(border = v)))
  ,'content':(color_patten,(lambda x:x),lambda x,v:(x.update(content = v)))
  ,'component':(color_patten,(lambda x:x),lambda x,v:(x.update(component = v)))
  ,'decoration':(color_patten,(lambda x:x),lambda x,v:(x.update(decoration = v)))}

set_timerange_handler = {'start':(time_range_patten,(lambda x:x),lambda x, v: (x.update(start = v)))
  ,'end':(time_range_patten,(lambda x:x),lambda x, v:(x.update(end=v)))}

def cpt_price(x,v):
  setattr(x,'pricelow',v.replace('From $',''))
  setattr(x,'pricehigh','2345')
  #setattr(x,'pricelow',v.split('-')[0])
  #setattr(x,'pricehigh',v.split('-')[1])

addserv_handler = {
   'latitude':(latlong_patten,(lambda x: int(eval(x)*1000000)),lambda x, v: setattr(x,'latitude',v))
  ,'longitude':(latlong_patten,(lambda x: int(eval(x)*1000000)),lambda x, v: setattr(x,'longitude',v))
  ,'name':(name_patten,(lambda x:x),lambda x, v:setattr(x,'name',v.replace(' ','-')))
  ,'type':(type_patten,(lambda x:x),lambda x, v:setattr(x,'type',v))
  ,'nation':(nation_patten,(lambda x:x),lambda x, v:setattr(x,'nation',v))
  ,'local':(name_patten,(lambda x:x),lambda x, v:setattr(x,'local',v))
  ,'phone':(phone_patten,(lambda x:x),lambda x, v:setattr(x,'phone',v))
  ,'price':(data_patten,(lambda x:x),cpt_price)
  ,'days':(day_patten,(lambda x:x),lambda x, v:setattr(x,'days',v))
  ,'description':(description_patten,(lambda x:x),lambda x, v:setattr(x,'description',v))
  ,'address':(address_patten,(lambda x:x),lambda x, v:setattr(x,'address',v))
  ,'icon':(url_patten,(lambda x:x),lambda x, v:setattr(x,'icon',v))
  ,'special_description':(url_patten,(lambda x:x),lambda x, v:setattr(x,'special_description',v))
  ,'special_rate':(url_patten,(lambda x:x),lambda x, v:setattr(x,'special_rate',v))
  ,'special_start':(url_patten,(lambda x:x),lambda x, v:setattr(x,'special_start',v))
  ,'special_end':(url_patten,(lambda x:x),lambda x, v:setattr(x,'special_end',v))
  ,'website':(url_patten,(lambda x:x),lambda x, v:setattr(x,'website',v))
  ,'oz_state':(oz_state_patten,(lambda x:x),lambda x, v:setattr(x,'oz_state',v))
  ,'region':(region_patten,(lambda x:x),lambda x, v:setattr(x,'region',v))
  ,'city':(city_patten,(lambda x:x),lambda x, v:setattr(x,'city',v))
  ,'keywords':(keywords_patten,(lambda x:x),lambda x, v:setattr(x,'keywords',v))}
  
mdyserv_handler = {
   'type':(type_patten,(lambda x:x),lambda x, v:setattr(x,'type',v))
  ,'phone':(phone_patten,(lambda x:x),lambda x, v:setattr(x,'phone',v))
  ,'price':(data_patten,(lambda x:x),cpt_price)
  ,'days':(day_patten,(lambda x:x),lambda x, v:setattr(x,'days',v))
  ,'description':(description_patten,(lambda x:x),lambda x, v:setattr(x,'description',v))
  ,'nation':(nation_patten,(lambda x:x),lambda x, v:setattr(x,'nation',v))
  ,'special_description':(description_patten,(lambda x:x),lambda x, v:setattr(x,'special_description',v))
  ,'special_rate':(description_patten,(lambda x:x),lambda x, v:setattr(x,'special_rate',v))
  ,'special_start':(description_patten,(lambda x:x),lambda x, v:setattr(x,'special_start',v))
  ,'special_end':(description_patten,(lambda x:x),lambda x, v:setattr(x,'special_end',v))
  ,'website':(url_patten,(lambda x:x),lambda x, v:setattr(x,'website',v))}

# add by mike for simplify the modify service basic information
mdysimple_serv_handler = {
   'type':(type_patten,(lambda x:x),lambda x, v:setattr(x,'type',v))
  ,'phone':(phone_patten,(lambda x:x),lambda x, v:setattr(x,'phone',v))
  ,'price':(data_patten,(lambda x:x),cpt_price)
  ,'days':(day_patten,(lambda x:x),lambda x, v:setattr(x,'days',v))
  ,'nation':(nation_patten,(lambda x:x),lambda x, v:setattr(x,'nation',v))
  ,'website':(url_patten,(lambda x:x),lambda x, v:setattr(x,'website',v))}

mdydesc_handler = {
  'description':(description_patten,(lambda x:x),lambda x, v:setattr(x,'description',v))}

addgallery_handler = {'name':(name_patten,(lambda x:x),lambda x, v: (x.update(name = v.lower().replace(' ','-'))))}

login_validater = {'name':name_patten,'password':password_patten}

login_handler = {'name':(name_patten,(lambda x:x),lambda x, v:x.update(name = v))
    ,'password':(password_patten,(lambda x:x),lambda x, v:x.update(password = v))}

reg_handler = {'name':(name_patten,(lambda x:x),lambda x, v:x.update(name = v))
    ,'password':(password_patten,(lambda x:x),lambda x, v:x.update(password = v))
    ,'email':(email_patten,(lambda x:x),lambda x, v:x.update(email=v))}

pwd_handler = {'password':(password_patten,(lambda x:x),lambda x, v:x.update(password = v))}

forget_pw_handler = {'email':(email_patten,(lambda x:x),lambda x, v:x.update(email = v))}

savelayout_handler = {'left':(layout_patten,(lambda x:x),lambda x, v: (x.update(left = v.split(','))))
  ,'middle':(layout_patten,(lambda x:x),lambda x, v: (x.update(middle = v.split(','))))
  ,'right':(layout_patten,(lambda x:x),lambda x, v: (x.update(right = v.split(','))))}


choose_template_handler = {'name':(name_patten,(lambda x:x),lambda x, v: (x.update(name = v)))}

xml_data_handler = {'id':(number_patten,(lambda x:x),lambda x, v: (x.update(name = v)))}

#UNIT TEST
if __name__ == "__main__":
    try:
        assert command_validate['latitude'].match("151.202377")
        assert latlong_patten.match("-33.890049")
        assert not latlong_patten.match("-33.8900490")
        assert not latlong_patten.match("abc")
        assert not latlong_patten.match("abc.bcd")
        assert not latlong_patten.match("245.123")

        assert email_patten.match("p_ssg@hotmail.com")
        assert email_patten.match("gaoxin.braceup@gmail.com")

        assert name_patten.match("xin,gao")
        assert not name_patten.match("$xin,gao")

        assert phone_patten.match("0449832333")
        assert not phone_patten.match("aab0098765")

        assert url_patten.match ("http://www.google.com")
        assert url_patten.match ("http://www.google.com/test.jpg")
        assert not url_patten.match ("abd://http://www.google.com/test.jpg")
        print "data.py SUCCESSFUL"
    except AssertionError:
        print "data.py FAIL!"
